package org.github.config;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.exception.NotSafeException;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.github.core.exception.ClientException;
import org.github.core.exception.RemoteException;
import org.github.core.exception.ServerException;
import org.github.core.exception.ValidException;
import org.github.core.spring.restful.json.JSONBase;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import static cn.hutool.core.collection.IterUtil.getFirst;
import static org.github.core.spring.util.MessageSourceUtil.i18n;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;

@RestControllerAdvice
@Slf4j
public class ExceptionController {
  @ExceptionHandler(NotLoginException.class)
  public JSONBase handleAuthException(Exception e) {
    //TODO
    return JSONBase.of(UNAUTHORIZED, e.getMessage());
  }

  @ExceptionHandler(ClientException.class)
  public JSONBase handleClientException(ClientException e) {
    val msg = i18n(e.getMessage(), e.getArgs());
    return JSONBase.of(BAD_REQUEST, msg);
  }

  @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
  public JSONBase handleHttpRequestMethodNotSupportedException(Exception e) {
    //TODO
    return JSONBase.of(BAD_REQUEST, e.getMessage());
  }

  @ExceptionHandler({NotPermissionException.class, NotRoleException.class, NotSafeException.class})
  public JSONBase handlePermException(Exception e) {
    //TODO
    return JSONBase.of(FORBIDDEN, e.getMessage());
  }

  @ExceptionHandler(RemoteException.class)
  public JSONBase handleRemoteException(RemoteException e) {
    return e.getData();
  }

  @ExceptionHandler(ServerException.class)
  public JSONBase handleServerException(ServerException e) {
    val msg = i18n(e.getMessage(), e.getArgs());
    log.warn(msg, e);
    return JSONBase.of(INTERNAL_SERVER_ERROR, msg);
  }

  @ExceptionHandler(Throwable.class)
  public JSONBase handleThrowable(Throwable e) {
    log.error(e.getMessage(), e);
    val msg = i18n("system.error", null);
    return JSONBase.of(INTERNAL_SERVER_ERROR, msg);
  }

  @ExceptionHandler(ValidException.class)
  public JSONBase handleValidException(ValidException e) {
    val result = e.getResult();
    val first = getFirst(result.notPassList());
    val msg = i18n(first.message(), null);
    return JSONBase.of(BAD_REQUEST, msg);
  }
}
